﻿using System.Diagnostics.Contracts;

namespace System.Reactive.Linq
{
	/// <summary>
	/// Provides a set of <see langword="static"/> methods for query operations over observable sequences.
	/// </summary>
	public static partial class Observable2
	{
#if WINDOWS_PHONE
		/// <summary>
		/// Converts the elements of an observable sequence to the specified type.
		/// </summary>
		/// <remarks>
		/// The existing <see cref="Observable.Cast{TResult}"/> operator only works on observable sequences of <see cref="object"/>.
		/// In Windows Phone, since <see cref="IObservable{T}"/> isn't covariant on <em>T</em>, sometimes casting is required between 
		/// strongly-typed sequences of data to work correctly with certain operators.  <see cref="Cast{TSource,TResult}"/> facilitates 
		/// this need.
		/// </remarks>
		/// <typeparam name="TSource">The object that provides notification information.</typeparam>
		/// <typeparam name="TResult">The type to which each object in the observable sequence is cast.</typeparam>
		/// <param name="source">The observable containing the values to be cast.</param>
		/// <returns>An observable sequence containing the elements of the source observable cast to the specified type.</returns>
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.StyleCop.CSharp.SpacingRules", "SA1008:OpeningParenthesisMustBeSpacedCorrectly",
			Justification = "Double cast.")]
		public static IObservable<TResult> Cast<TSource, TResult>(this IObservable<TSource> source)
		{
			Contract.Requires(source != null);
			Contract.Ensures(Contract.Result<IObservable<TResult>>() != null);

			return source.Select(value => (TResult) (object) value);
		}
#endif
	}
}